/********************************************************************************************/
/*																							*/
/*								Twn_TCPlanner.cpp											*/														
/*																							*/
/*	Date:			11/03/02																*/
/*	Author:			Matteo Tavella															*/	
/*	Description:	Library of functions to decompose Technological Cycles in micro op.		*/	
/*					following the rules described by DAFS file F_TSEQ						*/
/*					Perform also control over Technological Cycle feasibility				*/		
/*																							*/
/********************************************************************************************/
#define ALONE_TWN_TCPLAN
#include "Twn_TCPlanner.h"


int				TCP_Err;
TCHAR			TCP_LogMsg[128];
TCHAR			TCP_LogPath[128];
BOOL			TCP_LogActive;
BOOL			TCP_MsgBoxActive;

dynamic_struc	tempDyn;

BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // handle to DLL module
					DWORD fdwReason,     // reason for calling function
					LPVOID lpReserved )  // reserved
					{
	LONG	res;
	LPDWORD	type;
	LPBYTE	data;
	LPDWORD size;
	HKEY	hKey;
	TCHAR	szProductType[MY_BUFSIZE];
    DWORD	dwBufLen = MY_BUFSIZE;
	DWORD	active;
    
	size = 0;
	data = 0;
	type = 0;
	
	
	switch(fdwReason){ 
		case DLL_PROCESS_ATTACH:
			RegOpenKeyEx(	HKEY_LOCAL_MACHINE, 
							TEXT("SOFTWARE\\ABB\\Power Generation Portal\\Tianwan\\Twn_TCPlanner"),
							0,
							KEY_QUERY_VALUE,
							&hKey);
			res = RegQueryValueEx(	hKey,
									TEXT("LogPath"),
									NULL,
									NULL,
									(LPBYTE)szProductType,
									&dwBufLen);
			if(res == ERROR_SUCCESS)
				_stprintf_s(TCP_LogPath, (TCHAR*)szProductType);
			
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("LogActive"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				if((DWORD)active == 0)
					TCP_LogActive = false;
				else
					TCP_LogActive = true;
			}
			
			active = 0;
			dwBufLen = sizeof(active);
			res = RegQueryValueEx(	hKey,
									TEXT("MsgBoxActive"),
									NULL,
									NULL,
									(LPBYTE)&active,
									&dwBufLen);
			if(res == ERROR_SUCCESS){
				if((DWORD)active == 0)
					TCP_MsgBoxActive = false;
				else
					TCP_MsgBoxActive = true;
			}
			break;
		default:
			break;
	}
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCPlanner
**
** Input:			hWnd		-	Handle of the calling window to send proigress messages
**									If NULL messages won't be sent.
**
** Description:		Manage the the next technological cycle in F.PHAS DAFS file.
**
** Return:			PHASTAT		-	PH_NORMAL	-	TC successfully managed.
**								-	PH_XXXXXX	-	Otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
PHASTAT TCPlanner(HWND hWnd){
	RETCOND			retCnd;
	RETSTAT			retSt;
	PHASTAT			retPh;
	FILEIDX			filePhas;
	TECCYCID		tcId;
	MAC_CMDNAME		MacroCmdName;
	GENIDX			MacroCmdIdx;
	GENIDX			tc1GIdx;
	GENIDX			tc1HIdx;
	GENIDX			tc1H1Idx;
	phas_struc		phas;
	tc_seq			tcSeq;
	bool			sendMsg;
	bool			objInBuffer;
	bool			objInCell;
	int				numOp;
	int				firstMicroOp;
	int				lastMicroOp;
	int				currentPhase;
	int				nextPhase;
	int				redirect;
	int				checkedCells;
	int				errNum;
	int				mast;
	TCHAR			errMsg[TC_ERR_LEN + 1];

	filePhas.num = F_PHAS;

	if(hWnd == NULL)
		sendMsg = false;
	else
		sendMsg = true;
	
	GetDynCurrentMast(&mast);

	//Inializzo il buffer dei movimenti.//
	retSt = InitMoveBuffer();
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Cannot inizialize move buffer DAFS file."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(49));
		return(PH_FAILED);
	}

	//Prelevo il file con le informazioni dinamiche e lo salvo.//
	retSt = GetDynStruc(&tempDyn);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Cannot retrieve dynamic information."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(1));
		return(PH_FAILED);
	}

	//Controllo se posso avviare un ciclo tecnologico.//
	retSt = GetDynCurrentPhase(&currentPhase);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error retieving current technological cycle."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(2));
		SetDynStruc(tempDyn);
		return(PH_FAILED);
	}
	retSt = GetDynNextPhase(&nextPhase);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error retieving next technological cycle."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(3));
		return(PH_FAILED);
	}
	
	if((currentPhase == nextPhase) && (currentPhase != 0)){
		_stprintf_s(TCP_LogMsg, _T("Technological cycle %d is already in Execution."), currentPhase);
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(4));
		return(PH_INPROGR);
	}

	if(currentPhase != 0){
		_stprintf_s(TCP_LogMsg, _T("Cannot start Technological Cycle %d, Cylcle %d is already in Execution."), nextPhase, currentPhase);
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(5));
		return(PH_INPROGR);
	}
	retCnd = FileRead ( &filePhas, nextPhase, 1, &phas, sizeof(phas_struc));
	if(retCnd == R_NORMAL){
		//Inizializzo i timestamp della fase che sta per iniziare e scrivo sul DAFS file.//
		GetApmsTimeEx (&phas.sta_phse_time);
		retCnd = FileWrite (&filePhas, nextPhase, 1, &phas, sizeof(phas_struc));
		if(retCnd != R_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot write on DAFS file F.PHAS."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(6));
			return(PH_FAILED);
		}
		//Se la fase � la n�1 imposto anche il tempo di avvio della campagna.//
		if(currentPhase == 1)
			SetCampaignTime(0);
		retSt = SetPhaseStatus(phas.phase, PHAS_INEXECUTION);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_STARTED, NULL, NULL);
	}
	else{
		_stprintf_s(TCP_LogMsg, _T("Error: cannot read DAFS file F_PHAS."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(7));
		return (PH_FAILED);
	}
	
	retSt = SetDynCurrentPhase(nextPhase);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot set current phase number."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(8));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}

	retSt = SetSSTREntryEx(SSTR_TC_REC, NULL);
	retSt = SetSSTREntryEx(SSTR_COORD_REC, NULL);
	retSt = SetSSTREntryEx(SSTR_OBJ_REC, NULL);


	retSt = SetDynNextMove_a(1); 
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot set next automatic operation."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(9));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}
	
	retSt = SetDynCurrentOper(0);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot set current automatic operation."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(10));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}

	retSt = InitMicroCmdExe();
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot initialize DAFS file F.MICE."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(11));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}
	
	retSt = GetTechCycIdx(_T("1G"), &tc1GIdx);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve technological cycle \"1G\" identifier."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(11));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}

	retSt = GetTechCycIdx(_T("1H"), &tc1HIdx);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve technological cycle \"1H\" identifier."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(11));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		SetDynStruc(tempDyn);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}

	retSt = GetTechCycIdx(_T("1H1"), &tc1H1Idx);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve technological cycle \"1H1\" identifier."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(11));
		retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
		SetDynStruc(tempDyn);
		if(sendMsg)
			SendMessage(hWnd, WM_PH_END, NULL, NULL);
		return (PH_FAILED);
	}

	
	//Controllo se la fase contiene un ciclo tecnologico oppure un'operazione su DB.//
	if(phas.tecCycIdx == 0){
		retSt = GetPhaseMacroName(nextPhase, MacroCmdName);
		if(retSt == RT_NORMAL){
			//Prelevo l'Idx della macro-op.//
			retSt = GetMacroCmdIdx (MacroCmdName, &MacroCmdIdx );
			if(retSt == RT_NORMAL){
				if(!_tcscmp(MacroCmdName, MAC_DECL)){
					retPh = Pro_Ph_Decl();
					if(retPh != PH_NORMAL){
						_stprintf_s(TCP_LogMsg, _T("Error: DB operation \"Declare\" in phase %d failed."), nextPhase);
						TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(60));
						retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
						SetDynStruc(tempDyn);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
						return (retPh);
					}
					else{
						retSt = SetPhaseStatus(phas.phase, PHAS_EXECUTED);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
					}
				}
				else if(!_tcscmp(MacroCmdName, MAC_INSR)){
					retPh = Pro_Ph_Insr();
					if(retPh != PH_NORMAL){
						_stprintf_s(TCP_LogMsg, _T("Error: DB operation \"Insert\" in phase %d failed."), nextPhase);
						TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(61));
						retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
						SetDynStruc(tempDyn);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
						return (retPh);
					}
					else{
						retSt = SetPhaseStatus(phas.phase, PHAS_EXECUTED);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
					}
				}
				else if(!_tcscmp(MacroCmdName, MAC_REMO)){
					retPh = Pro_Ph_Remo();
					if(retPh != PH_NORMAL){
						_stprintf_s(TCP_LogMsg, _T("Error: DB operation \"Remove\" in phase %d failed."), nextPhase);
						TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(62));
						retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
						SetDynStruc(tempDyn);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
						return (retPh);
					}
					else{
						retSt = SetPhaseStatus(phas.phase, PHAS_EXECUTED);
						if(sendMsg)
							SendMessage(hWnd, WM_PH_END, NULL, NULL);
					}
				}
			}
			else{
				_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve macro command idx for %s."), MacroCmdName);
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(63));
				retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
				SetDynStruc(tempDyn);
				if(sendMsg)
					SendMessage(hWnd, WM_PH_END, NULL, NULL);
				return (PH_INVMAC);
			}
		}
	}
	else if(phas.tecCycIdx == tc1GIdx){
		checkedCells = 0;
		retPh = DCIPlanner(&checkedCells);
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error planning technological cycle \"1G\"."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}
		if(checkedCells == 0){
			MessageBox(hWnd, _T("Technological Cycle 1G, can't be executed because all reactor cells are empty."), _T("Attention"), MB_OK | MB_ICONINFORMATION);
			retSt = SetPhaseStatus(phas.phase, PHAS_EXECUTED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return(PH_NORMAL);
		}
		else{
			retSt = SetPhaseStatus(phas.phase, PHAS_PLANNED);
			tempDyn.current_phase = nextPhase;
			tempDyn.next_phase = nextPhase;
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_STARTED, NULL, NULL);
			return(PH_NORMAL);
		}
		
	}
	else if(phas.tecCycIdx == tc1HIdx){
		checkedCells = 0;
		retPh = DMPPlanner(&checkedCells);
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error planning technological cycle \"1H\"."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}
		if(checkedCells == 0){
			MessageBox(hWnd, _T("Technological Cycle 1H, can't be executed because all reactor cells are full."), _T("Attention"), MB_OK | MB_ICONINFORMATION);
			retSt = SetPhaseStatus(phas.phase, PHAS_EXECUTED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return(PH_NORMAL);
		}
		else{
			retSt = SetPhaseStatus(phas.phase, PHAS_PLANNED);
			tempDyn.current_phase = nextPhase;
			tempDyn.next_phase = nextPhase;
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return(PH_NORMAL);
		}
	}else if(phas.tecCycIdx == tc1H1Idx){
		retPh = DMPPlannerSingle();
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error planning technological cycle \"1H1\"."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}else{
			retSt = SetPhaseStatus(phas.phase, PHAS_PLANNED);
			tempDyn.current_phase = nextPhase;
			tempDyn.next_phase = nextPhase;
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return(PH_NORMAL);
		}
	}
	else{
		if(mast == FALC_MAST){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot start technological cycles when FALV is mounted."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		
		}
		if(mast == DMP_MAST){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot start technological cycles when DMP is mounted."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		
		}
		//Carico la sequenza relativa al ciclo Tecnologico da svolgere//
		retSt = GetTechCycId(phas.tecCycIdx, tcId);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve technological cycle Id."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(12));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}

		retSt = GetTCOpSeq(tcId, &tcSeq);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve technological cycle Sequence."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(13));
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			SetDynStruc(tempDyn);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}

		//Pianifico in sequenza le operazioni//
		for(numOp = 0; numOp < tcSeq.numOp; numOp++){
			objInBuffer = false;
			objInCell = false;
			retSt = CheckOpCondition(tcSeq.seq[numOp], &redirect, &errNum);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: operation condition check failed."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(53));
				SetDynStruc(tempDyn);
				retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_PH_END, NULL, NULL);
				return (PH_FAILED);
			}
			if((redirect > 0) && (redirect <= N_MAX_TC_SEQ)){
				numOp = redirect - 1;
				continue;
			}

			if(errNum > 0){
				//Manage Errors//
				retSt = GetErrMsg(errNum, errMsg);
				if(retSt == RT_NORMAL){
					_stprintf_s(TCP_LogMsg, _T("Technological cycle failed. %s."), errMsg);
					TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(100 + errNum));
				}
				SetDynStruc(tempDyn);
				retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_PH_END, errNum, NULL);
				return (PH_FAILED);
			}
			
			retSt = GetDynNextMove_a(&firstMicroOp);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Cannot retrieve next automatic micro operation index."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(57));
				SetDynStruc(tempDyn);
				retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
				if(sendMsg)
					SendMessage(hWnd, WM_PH_END, NULL, NULL);
				return (PH_FAILED);
			}

			if(_tcscmp(tcSeq.seq[numOp].opType, _T("NULL"))){
				retPh = TCPExeOp(tcSeq.seq[numOp], numOp, tcSeq.techCycIdx);
				if(retPh != PH_NORMAL){
					retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_PH_END, NULL, NULL);
					return(PH_FAILED);
				}

				retSt = GetDynNextMove_a(&lastMicroOp);
				if(retSt != RT_NORMAL){
					_stprintf_s(TCP_LogMsg, _T("Cannot retrieve next automatic micro operation index."));
					TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(58));
					SetDynStruc(tempDyn);
					retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_PH_END, NULL, NULL);
					return (PH_FAILED);
				}

				retSt = SetMiceTCInfo(firstMicroOp, lastMicroOp - 1, tcSeq.techCycIdx, numOp);
				if(retSt != RT_NORMAL){
					_stprintf_s(TCP_LogMsg, _T("Cannot set micro command file TC info."));
					TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(59));
					SetDynStruc(tempDyn);
					retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
					if(sendMsg)
						SendMessage(hWnd, WM_PH_END, NULL, NULL);
					return (PH_FAILED);
				}
				
				if(sendMsg)
					SendMessage(hWnd, WM_PH_STEP, NULL, NULL);
			}

			if(redirect > N_MAX_TC_SEQ)
				numOp = redirect;
		}

		retSt = MiceOptimizer(nextPhase);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Micro Command Optimizer has failed."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(47));
			SetDynStruc(tempDyn);
			retSt = SetPhaseStatus(phas.phase, PHAS_FAILED);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_END, NULL, NULL);
			return (PH_FAILED);
		}
		else{
			retSt = SetPhaseStatus(phas.phase, PHAS_PLANNED);
			if(sendMsg)
				SendMessage(hWnd, WM_PH_STARTED, NULL, NULL);
		}
	}
	tempDyn.current_phase = nextPhase;
	tempDyn.next_phase = nextPhase;
	SetDynStruc(tempDyn);
	return(PH_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_ActivateLog
**
** Description:		Activate the Log file.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_ActivateLog(void){
	TCP_LogActive = true;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_DeactivateLog
**
** Description:		Deactivate the Log file.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_DeactivateLog(void){
	TCP_LogActive = false;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_ActivateMsgBox
**
** Description:		Activate the message box error messages.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_ActivateMsgBox(void){
	TCP_MsgBoxActive = true;
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_DeactivateMsgBox
**
** Description:		Deactivate the message box error messages.
**
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_DeactivateMsgBox(void){
	TCP_MsgBoxActive = false;
	return 0;
}
/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_SetLogPath
**
** Description:		Cahge the Log file path.
**
** Input:			path			- New Log file path.
** Return:			int				- 0 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_SetLogPath(TCHAR *path){
	_tcscpy_s(TCP_LogPath, path);
	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCP_LogFileWrite
**
** Description:		Print a message in the application log file,
**
** Input:			cmd				- _T("ERR") - error, _T("WRN") - warning, _T("OK ") - success.
**					Comment			- Message description.
**
** Return:			int				- 1 for success.
**									- -1 otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
int TCP_LogFileWrite(TCHAR cmd[4], TCHAR *Comment, int errNum){
	FILE		*LogFile;
	TCHAR		newLine = '\n';
	SYSTEMTIME	timeStamp;
	TCHAR		tempStr[256];
	TCHAR		timeStr[100];
	
	if(TCP_LogActive){

		errno_t err;
		err = _tfopen_s(&LogFile,TCP_LogPath, _T("a"));
		if (err != 0)
			return -1;

		//LogFile = _tfopen(TCP_LogPath, _T("a"));
		//if(LogFile == NULL)
		//	return -1;
		
		GetSystemTime(&timeStamp);
		_stprintf_s(timeStr, _T("[hh%2d  mm%2d  ss%2d,%3d (GMT)] [%2d-%2d-%4d]"), timeStamp.wHour, timeStamp.wMinute, timeStamp.wSecond, timeStamp.wMilliseconds, timeStamp.wDay, timeStamp.wMonth, timeStamp.wYear);
		if(_tcscmp(cmd, _T("ERR")) == 0)
			_ftprintf(LogFile,_T("%s   %s  %s Err.N� %d.%c"), timeStr, cmd, Comment, errNum,  newLine);
		else
			_ftprintf(LogFile,_T("%s   %s  %s%c"), timeStr, cmd, Comment, newLine);
		if(fclose(LogFile)!=0)
			return -1;
	}
		
	if((TCP_MsgBoxActive) && (_tcscmp(cmd, _T("ERR")) == 0)){
		_stprintf_s(tempStr, _T("Error n.%d, %s"), errNum, Comment);
		MessageBox(NULL, tempStr, _T("Error"), MB_OK | MB_ICONERROR);
	}

	return 0;
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		CheckOpCondition
**
** Description:		Check a TC operation condition and if needed executes requested actions.
**
** Input:			t_tc_op			- TC operation structure
** Output:			opToJump		- Operation index to jump to (if Action is Jump, -1 otherwise)
**
** Return:			RETSTAT			- RT_NORMAL for success.
**									- RT_XXXXXX otherwise.
** 
**********************************************************************************************
*********************************************************************************************/
RETSTAT CheckOpCondition(t_tc_op opStruct, int *opToJump, int *errNum){
	RETSTAT			retSt;
	PHASTAT			retPh;
	RETCOND			retCnd;
	tc_seq			condTcSeq;
	int				step;
	int				i;
	bool			exeAction;
	OBJTMM			mastSituation;
	int				objtGenCode;
	short int		vx;
	short int		vy;
	int				currPhase;
	OBJTCELL		objtCell;
	move_buffer		movBuf;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	TAGNAME			tagName;
	GENIDX			cellType;

	exeAction = false;
	*opToJump = -1;
	*errNum = 0;

	retSt = GetDynCurrentPhase(&currPhase);
	if((retSt != RT_NORMAL) || (currPhase <= 0))
		return(RT_FAILED);
	
	//Controllo la condizione//
	switch(opStruct.opCond.condType){
	case COND_NULL:
		return(RT_NORMAL);
		break;
	case COND_ALWAYS:
		exeAction = true;
		break;
	case COND_CHECK_MAST:
		if(opStruct.opCond.not == 1){
			retSt = GetObjtGenericTypeCode(opStruct.opCond.objtIdx, &objtGenCode);
			if(retSt != RT_NORMAL)
				return(retSt);
			retSt = GetMastSituation(&mastSituation);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(mastSituation.obj[objtGenCode] == opStruct.opCond.objtIdx)
				exeAction = false;
			else
				exeAction = true;
		}
		else{
			retSt = GetObjtGenericTypeCode(opStruct.opCond.objtIdx, &objtGenCode);
			if(retSt != RT_NORMAL)
				return(retSt);
			retSt = GetMastSituation(&mastSituation);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(mastSituation.obj[objtGenCode] == opStruct.opCond.objtIdx)
				exeAction = true;
			else
				exeAction = false;
		}
		break;
	case COND_CHECK_CELL_TYPE:
		if(opStruct.opCond.not == 1){
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);
			
			retSt = GetCellType(vx, vy, &cellType);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			if(cellType == opStruct.opCond.objtIdx)
				exeAction = false;
			else
				exeAction = true;
		}
		else{
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);
			
			retSt = GetCellType(vx, vy, &cellType);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			if(cellType == opStruct.opCond.objtIdx)
				exeAction = true;
			else
				exeAction = false;
		}
		break;
	case COND_CHECK_CELL:
		if(opStruct.opCond.not == 1){
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);

			retSt = GetObjtGenericTypeCode(opStruct.opCond.objtIdx, &objtGenCode);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			retSt = GetCellSituation(vx, vy, &objtCell);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(objtCell.obj[objtGenCode] == opStruct.opCond.objtIdx)
				exeAction = false;
			else{
				if(CheckMoveBufferEntry(vx, vy,  opStruct.opCond.objtIdx, &movBuf) == RT_NORMAL)
					exeAction = false;
				else
					exeAction = true;
			}
		}
		else{
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);

			retSt = GetObjtGenericTypeCode(opStruct.opCond.objtIdx, &objtGenCode);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			retSt = GetCellSituation(vx, vy, &objtCell);
			if(retSt != RT_NORMAL)
				return(retSt);
			if(objtCell.obj[objtGenCode] == opStruct.opCond.objtIdx)
				exeAction = true;
			else{
				if(CheckMoveBufferEntry(vx, vy,  opStruct.opCond.objtIdx, &movBuf) == RT_NORMAL)
					exeAction = true;
				else
					exeAction = false;
			}
		}
		break;
	case COND_MAST_MOUNT:
		if(opStruct.opCond.not == 1){
			switch(opStruct.opCond.mastType){
			case MAIN_MAST:
				_stprintf_s(tagName, TWN_MM_MOUNT);
				break;
			case TV_MAST:
				_stprintf_s(tagName, TWN_TV_MOUNT);
				break;
			}
			retCnd = GetTagIdx(tagName, &tagIdx);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = TagRead(&tagIdx, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
				exeAction = true;
			else
				exeAction = false;
		}
		else{
			switch(opStruct.opCond.mastType){
			case MAIN_MAST:
				_stprintf_s(tagName, TWN_MM_MOUNT);
				break;
			case TV_MAST:
				_stprintf_s(tagName, TWN_TV_MOUNT);
				break;
			}
			retCnd = GetTagIdx(tagName, &tagIdx);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			retCnd = TagRead(&tagIdx, &tagVal);
			if(retCnd != R_NORMAL)
				return(RT_FAILED);
			if(GtBit((short int)(tagVal.value.val_di), 15) == 1)
				exeAction = false;
			else
				exeAction = true;
		}
		break;
	case COND_CELL_IS_EMPTY:
		if(opStruct.opCond.not == 1){
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);
			
			retSt = GetCellSituation(vx, vy, &objtCell);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			exeAction = false;
			for(i = 0; i < N_MAX_NONAM_OBJ; i++){
				if(objtCell.obj[i] != 0){
					exeAction = true;
					break;
				}
			}
			if(!exeAction){
				if(CheckMoveBufferEntry(vx, vy, -1, &movBuf) == RT_NORMAL)
					exeAction = true;
			}
		}
		else{
			if((opStruct.opCond.vx == COND_SV_XY) && (opStruct.opCond.vy == COND_SV_XY)){
				retSt = GetPhaseSourceVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_DV_XY) && (opStruct.opCond.vy == COND_DV_XY)){
				retSt = GetPhaseDestVirtCoo(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_HECA_XY) && (opStruct.opCond.vy == COND_HECA_XY)){
				retSt = GetPhaseHECACoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}
			else if((opStruct.opCond.vx == COND_FFDS_XY) && (opStruct.opCond.vy == COND_FFDS_XY)){
				retSt = GetPhaseFFDSCoord(currPhase, &vx, &vy);
				if(retSt != RT_NORMAL)
					return(retSt);
			}else if((opStruct.opCond.vx == COND_CC_XY) && (opStruct.opCond.vy == COND_CC_XY)){
				vx = CP1_VX;
				vy = CP1_VY;
			}
			else if((opStruct.opCond.vx != 0) && (opStruct.opCond.vy != 0)){
				vx = opStruct.opCond.vx;
				vy = opStruct.opCond.vy;
			}
			else
				return(RT_FAILED);
			
			retSt = GetCellSituation(vx, vy, &objtCell);
			if(retSt != RT_NORMAL)
				return(retSt);
			
			exeAction = true;
			for(i = 0; i < N_MAX_NONAM_OBJ; i++){
				if(objtCell.obj[i] != 0){
					exeAction = false;
					break;
				}
			}
			if(exeAction){
				if(CheckMoveBufferEntry(vx, vy, -1, &movBuf) == RT_NORMAL)
					exeAction = false;
			}
		}
		break;
	case COND_MAST_IS_EMPTY:
		if(opStruct.opCond.not == 1){
			retSt = GetMastSituation(&mastSituation);
			if(retSt != RT_NORMAL)
				return(retSt);
			exeAction = false;
			for(i = 0; i < N_MAX_NONAM_OBJ; i++){
				if(mastSituation.obj[i] != 0){
					exeAction = true;
					break;
				}
			}
		}
		else{
			retSt = GetMastSituation(&mastSituation);
			if(retSt != RT_NORMAL)
				return(retSt);
			exeAction = true;
			for(i = 0; i < N_MAX_NONAM_OBJ; i++){
				if(mastSituation.obj[i] != 0){
					exeAction = false;
					break;
				}
			}
		}
		break;
	default:
		return(RT_FAILED);
	}

	if(exeAction){
		switch(opStruct.opCond.actionType){
		case ACTION_JUMP:
			if(opStruct.opCond.goTo > 0)
				*opToJump = opStruct.opCond.goTo - 1;
			else
				*opToJump = N_MAX_TC_SEQ + 1;
			break;
		case ACTION_JUMPEX:
			*opToJump = -1;
			retSt = GetTCOpSeq(opStruct.opCond.tcId, &condTcSeq);
			if(retSt != RT_NORMAL)
				return(retSt);
			for(step = opStruct.opCond.fromOp - 1; step < opStruct.opCond.toOp; step++){
				retPh = TCPExeOp(condTcSeq.seq[step], step, condTcSeq.techCycIdx);
				if(retPh != PH_NORMAL)
					return (RT_FAILED);
			}
			
			break;
		case ACTION_ERR:
			*errNum = opStruct.opCond.goTo;
			return(RT_NORMAL);
		default:
			return(RT_FAILED);
		}
	}
	else
		*opToJump = -1;

	return(RT_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		TCPExeOp
**
** Description:		Manage an operation described in a t_tc_op structure
**
** Input:			t_tc_op			- TC operation structure
**					opNum			- sequence number in technological cycle
**					tecCycIdx		- Identifier of the technological cycle.
**
** Return:			PHASTAT			- PH_NORMAL for success
**									- PH_XXXXXX otherwise
** 
**********************************************************************************************
*********************************************************************************************/
PHASTAT TCPExeOp(t_tc_op opToExecute, int numOp, GENIDX tecCycIdx){
	RETSTAT			retSt;
	PHASTAT			retPh;
	short int		dvx, dvy;
	float			dynx, dyny;
	GENIDX			zoneIdx;
	GENIDX			objtIdx;
	GENIDX			objIdx;
	int				objtGenCode;
	OBJTMM			mastSituation;
	t_cell			cell;
	TV_angle		range;
	OBJTNAME		objtName;
	OBJNAME			objName;
	move_buffer		movBuf;
	bool			objInBuffer;
	bool			objInCell;
	OBJTCELL		objtCell;
	int				cellType;
	int				phasNum;
	int				rotFlag;
	phas_struc		phas;
	float			dynTVAngle;
	float			markTVAngle;
	
	objInBuffer = false;
	objInCell = false;

	//Controllo quale operazione eseguire.//
	//Movimentazione (X,Y)//
	if(!_tcscmp(opToExecute.opType, _T("MOVE"))){
		retSt = GetDynMmxyPos(&dynx, &dyny);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot retrieve dymic mast position."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(16));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
		retSt = GetTCOpSeqCoordinates(tecCycIdx, numOp, &dvx, &dvy);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot retrieve Technological Cycle sequence coordinates."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(17));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current mast situation."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(18));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retPh = Mov_xy(0, 0, dvx, dvy, dynx, dyny, 0, 0, -1);
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: movement planning to cell (%d,%d) has failed."), dvx, dvy);
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(19));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
	}
		
	//Inserimento di un oggetto in una cella //
	else if(!_tcscmp(opToExecute.opType, _T("INSERT"))){
		
		retSt = GetObjtIdx(opToExecute.par_1, &objtIdx);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve code of the object type in the sequence."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(20));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetObjtGenericTypeCode(objtIdx, &objtGenCode);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve generic code of the object type in the sequence."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(21));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetTCOpSeqCoordinates(tecCycIdx, numOp, &dvx, &dvy);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot retrieve operation virtual coodinates."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(22));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
			
		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current mast situation."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(23));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
			
		retSt = GetZoneIdxVirtCoo(dvx, dvy, &zoneIdx);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current zone identifier."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(23));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
		
		retSt = FindMoveBufferEntry(dvx, dvy, &movBuf);
		if(retSt == RT_NORMAL)
			memcpy(&objtCell, &movBuf.cellSituation, sizeof(OBJTCELL));
		else if(retSt == RT_NOTINMOVBUF){
			retSt = GetCellSituation(dvx, dvy, &objtCell);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current cell situation."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(24));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
		}
		else{
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve movement buffer entry."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(24));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetObjtName(objtIdx, objtName);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve object type name."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		if(mastSituation.obj[objtGenCode] != objtIdx){
			_stprintf_s(TCP_LogMsg, _T("Error: no object of type %s present on mast."), objtName);
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(26));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetDynCurrentPhase(&phasNum);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current phase number."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetPhase(phasNum, &phas);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current phase data."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		if((phas.markReq != 0) && (((phas.SV_X == dvx) && (phas.SV_Y == dvy)) || ((phas.DV_X == dvx) && (phas.DV_Y == dvy)))){
			retSt = GetDynTVAngle(&dynTVAngle);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve dynamic TV angle."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			
			if(IsMarkingAngle(dynTVAngle) == RT_FAILED){
				retSt = GetCellRotRange(dvx, dvy, &range, &rotFlag);
				if(retSt != RT_NORMAL){
					_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve cell TV rotation parameters."));
					TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
					SetDynStruc(tempDyn);
					return (PH_FAILED);
				}
				if(rotFlag != 0){
					retSt = CheckAngleInRange(range, dynTVAngle);
					if(retSt == RT_FAILED){
						_stprintf_s(TCP_LogMsg, _T("Error checking rotation feasibility"));
						TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
						SetDynStruc(tempDyn);
						return (PH_FAILED);
					}
					else if(retSt == RT_NORMAL){
						retSt = GetBestAngle(range,	dynTVAngle, 1, &markTVAngle);
						if(retSt == RT_NORMAL){
							retPh = Exec_Seq_TV(markTVAngle);
							if(retPh != PH_NORMAL){
								_stprintf_s(TCP_LogMsg, _T("Error adding TV rotation for marking positioning."));
								TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(45));
								SetDynStruc(tempDyn);
								return (retPh);
							}
						}
					}
				}
			}
		}

		if(objtGenCode >= N_MAX_NAMED_OBJ){
			//UnNamed objects//
			retPh = Exec_Seq(MICRO_INSERT, 0, objtIdx, zoneIdx, dvx, dvy, &cell.objt_cell, &mastSituation);
			if(retPh != PH_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: insert of object %s from cell (%d,%d) has failed."), objtName, dvx, dvy);
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(27));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = GetCellType(dvx, dvy, &cellType);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to retrieve cell type."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(28));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = InsertObject(&objtCell, &mastSituation, 0, objtIdx, cellType);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update DB after object insertion."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(28));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = UpdateMastSituation(&mastSituation);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update dynamic mast situation after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(29));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			movBuf.vx = dvx;
			movBuf.vy = dvy;
			memcpy(&movBuf.cellSituation, &objtCell, sizeof(OBJTCELL));
			retSt = MoveBufferAppend(movBuf);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Cannot add an entry to move buffer DAFS file."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(50));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
		}
		else{
			//Named objects//
			retSt = GetObjName(mastSituation.o_id[objtGenCode], objName);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: cannot find the name of the object to remove."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(30));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retPh = Exec_Seq(MICRO_INSERT, mastSituation.o_id[objtGenCode], objtIdx, zoneIdx, dvx, dvy, &cell.objt_cell, &mastSituation);
			if(retPh != PH_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: insertion of object %s from cell (%d,%d) has failed."), objName, dvx, dvy);
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(31));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = GetCellType(dvx, dvy, &cellType);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to retrieve cell type."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(28));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = InsertObject(&objtCell, &mastSituation, mastSituation.o_id[objtGenCode], objtIdx, cellType);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update DB after object insertion."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(32));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = UpdateMastSituation(&mastSituation);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update dynamic mast situation after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(33));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			movBuf.vx = dvx;
			movBuf.vy = dvy;
			memcpy(&movBuf.cellSituation, &objtCell, sizeof(OBJTCELL));
			retSt = MoveBufferAppend(movBuf);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Cannot add an entry to move buffer DAFS file."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(51));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
		}
	}
	//Rimozione di un oggetto da una cella//
	else if(!_tcscmp(opToExecute.opType, _T("REMOVE"))){
		retSt = GetObjtIdx(opToExecute.par_1, &objtIdx);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve code of the object type in the sequence."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(34));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetObjtGenericTypeCode(objtIdx, &objtGenCode);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve generic code of the object type in the sequence."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(35));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetTCOpSeqCoordinates(tecCycIdx, numOp, &dvx, &dvy);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot find current operation virtual coordinates."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(48));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
		
		retSt = GetMastSituation(&mastSituation);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current mast situation."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(36));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
			
		retSt = GetZoneVirtPar(dvx, dvy, &zoneIdx, &cell);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current cell situation."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(37));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetObjtName(objtIdx, objtName);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve object type name."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(13));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		if(CheckMoveBufferEntry(dvx, dvy, objtIdx, &movBuf) == RT_NORMAL)
			objInBuffer = true;
		else if(cell.objt_cell.obj[objtGenCode] == objtIdx)
			objInCell = true;

		if((!objInCell) && (!objInBuffer)){
			_stprintf_s(TCP_LogMsg, _T("Error: no object of type %s present in cell (%d,%d)."), objtName, dvx, dvy);
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(38));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetDynCurrentPhase(&phasNum);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current phase number."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retSt = GetPhase(phasNum, &phas);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve current phase data."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		if((phas.markReq != 0) && (((phas.SV_X == dvx) && (phas.SV_Y == dvy)) || ((phas.DV_X == dvx) && (phas.DV_Y == dvy)))){
			retSt = GetDynTVAngle(&dynTVAngle);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve dynamic TV angle."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			
			if(IsMarkingAngle(dynTVAngle) == RT_FAILED){
				retSt = GetCellRotRange(dvx, dvy, &range, &rotFlag);
				if(retSt != RT_NORMAL){
					_stprintf_s(TCP_LogMsg, _T("Error: cannot retrieve cell TV rotation parameters."));
					TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
					SetDynStruc(tempDyn);
					return (PH_FAILED);
				}
				if(rotFlag != 0){
					retSt = CheckAngleInRange(range, dynTVAngle);
					if(retSt == RT_FAILED){
						_stprintf_s(TCP_LogMsg, _T("Error checking rotation feasibility"));
						TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(25));
						SetDynStruc(tempDyn);
						return (PH_FAILED);
					}
					else if(retSt == RT_NORMAL){
						retSt = GetBestAngle(range,	dynTVAngle, 1, &markTVAngle);
						if(retSt == RT_NORMAL){
							retPh = Exec_Seq_TV(markTVAngle);
							if(retPh != PH_NORMAL){
								_stprintf_s(TCP_LogMsg, _T("Error adding TV rotation for marking positioning."));
								TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(45));
								SetDynStruc(tempDyn);
								return (retPh);
							}
						}
					}
				}
			}
		}

		if(objtGenCode >= N_MAX_NAMED_OBJ){
			//UnNamed objects//
			if(objInCell)
				memcpy(&objtCell, &cell.objt_cell, sizeof(OBJTCELL));
			else if(objInBuffer)
				memcpy(&objtCell, &movBuf.cellSituation, sizeof(OBJTCELL));
			else{
				_stprintf_s(TCP_LogMsg, _T("Object to move isn't present in Cell nor in movement buffer."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(51));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retPh = Exec_Seq(MICRO_REMOVE, 0, objtIdx, zoneIdx, dvx, dvy, &objtCell, &mastSituation);
			if(retPh != PH_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: removal of object %s from cell (%d,%d) has failed."), objtName, dvx, dvy);
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(39));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = RemoveObject(&objtCell, &mastSituation, 0, objtIdx);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update DB after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(40));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = UpdateMastSituation(&mastSituation);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update dynamic mast situation after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(41));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			movBuf.vx = dvx;
			movBuf.vy = dvy;
			memcpy(&movBuf.cellSituation, &objtCell, sizeof(OBJTCELL));
			retSt = MoveBufferAppend(movBuf);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Cannot add an entry to move buffer DAFS file."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(51));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
		}
		else{
			//Named objects//
			if(objInCell){
				objIdx = cell.objt_cell.o_id[objtGenCode];
				memcpy(&objtCell, &cell.objt_cell, sizeof(OBJTCELL));
			}
			else if(objInBuffer){
				objIdx = movBuf.cellSituation.o_id[objtGenCode];
				memcpy(&objtCell, &movBuf.cellSituation, sizeof(OBJTCELL));
			}
			else{
				_stprintf_s(TCP_LogMsg, _T("Object to move isn't present in Cell nor in movement buffer."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(52));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = GetObjName(objIdx, objName);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: cannot find the name of the object to remove."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(42));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retPh = Exec_Seq(MICRO_REMOVE, objIdx, objtIdx, zoneIdx, dvx, dvy, &objtCell, &mastSituation);
			if(retPh != PH_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: removal of object %s from cell (%d,%d) has failed."), objName, dvx, dvy);
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(43));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = RemoveObject(&objtCell, &mastSituation, objIdx, objtIdx);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update DB after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(44));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			retSt = UpdateMastSituation(&mastSituation);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Error: unable to update dynamic mast situation after object removal."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(45));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
			movBuf.vx = dvx;
			movBuf.vy = dvy;
			memcpy(&movBuf.cellSituation, &objtCell, sizeof(OBJTCELL));
			retSt = MoveBufferAppend(movBuf);
			if(retSt != RT_NORMAL){
				_stprintf_s(TCP_LogMsg, _T("Cannot add an entry to move buffer DAFS file."));
				TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(51));
				SetDynStruc(tempDyn);
				return (PH_FAILED);
			}
		}
	}
	//FA displacing movement//
	else if(!_tcscmp(opToExecute.opType, _T("DISPL"))){
		retSt = GetDynMmxyPos(&dynx, &dyny);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot retrieve dymic mast position."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(16));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
		retSt = GetTCOpSeqCoordinates(tecCycIdx, numOp, &dvx, &dvy);
		if(retSt != RT_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Cannot retrieve Technological Cycle sequence coordinates."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(17));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}

		retPh = Exec_Seq_Displ(dvx, dvy);
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: FA displacing in cell (%d,%d) has failed."), dvx, dvy);
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(19));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
	}
	//Marking Inspection (solo SW).//
	else if(!_tcscmp(opToExecute.opType, _T("INSP"))){
		retPh = Exec_Seq_TV_Insp();
		if(retPh != PH_NORMAL){
			_stprintf_s(TCP_LogMsg, _T("Error: TV marking inspection planning is failed."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(45));
			SetDynStruc(tempDyn);
			return (retPh);
		}
	}
	else if(!_tcscmp(opToExecute.opType, _T("NULL"))){
		return(PH_NORMAL);
	}
	//Errore nella sequenza//
	else{
		_stprintf_s(TCP_LogMsg, _T("Error: unknown operation in Technological Cycle sequence."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	}

	return(PH_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		DCIPlanner
**
** Description:		Execute planning for Fuel Assembly Level Control Technological Cycle (1G)
**
** Output:			numCellChecked	- Number of cells checked by FA level monitor (DCI)
**
** Return:			PHASTAT			- PH_NORMAL for success
**									- PH_XXXXXX otherwise
** 
**********************************************************************************************
*********************************************************************************************/
PHASTAT DCIPlanner(int *numCellChecked){
	RETCOND			retCnd;
	RETSTAT			retSt;
	PHASTAT			retPh;
	TAGVALEX		tagVal;
	TAGIDX			tagIdx;
	t_cell			cell;
	FILEIDX			fileIdx;
	GENIDX			reactZoneIdx;
	int				rec;
	GENIDX			mastType;
	short int		lastVX, lastVY;
	float			dynX, dynY;
	int				startRec;
	float			angle;
	int				counter;
	bool			insReact;
	bool			tvMount;
	micro_cmd_exe	mice;
	
	lastVX = 0;
	lastVY = 0;
	dynX = 0.0;
	dynY = 0.0;
	startRec = 0;
	counter = 0;
	*numCellChecked = 0;
	
	retCnd = GetTagIdx(TWN_TV_MOUNT, &tagIdx);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1)
		tvMount = true;
	else
		tvMount = false;

	retSt = GetZoneIdx(ZONE_REACTOR, &reactZoneIdx);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);
	
	fileIdx.num = F_CE01 + reactZoneIdx - 1;
	
	retSt = GetDynCurrentMast(&mastType);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);

	if(mastType != FALC_MAST)
		return(PH_FAILED);

	retSt = GetMastPosEx(mastType, &dynX, &dynY);
	if(retSt !=RT_NORMAL)
		return(PH_FAILED);
	
	//Controlla qui se FALV � nel reattore e TV...//
	InsideReact(dynX, dynY, &insReact);
	if(!insReact){
		_stprintf_s(TCP_LogMsg, _T("Error: FALVL is not inside reactor."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	}

	if(tvMount){
		retSt = GetDynTVAngle(&angle);
		if(retSt != RT_NORMAL)
			return(PH_FAILED);	

		if((angle <= 135.0 - TOLL_MM) || (angle >= 135.0 + TOLL_MM)){
			_stprintf_s(TCP_LogMsg, _T("Error: TV mast must be at 135� to start FALVL technological cycle."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
	}

	for(rec = 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			continue;
		if(cell.type != CELL_FA)
			continue;

		if(cell.objt_cell.obj[OBJT_N_FA] != 0){
			retSt = GetMastPosEx(FALC_MAST, &dynX, &dynY);
			if(retSt !=RT_NORMAL)
				return(PH_FAILED);

			retPh = Mov_xy_local(0, 0, cell.Virt_X, cell.Virt_Y, dynX, dynY, 0, 0 , angle, angle);
			if(retPh != PH_NORMAL)
				return(retPh);
			
			retPh = Exec_Seq_DCI(cell.Virt_X, cell.Virt_Y);
			if(retPh != PH_NORMAL)
				return(retPh);

			lastVX = cell.Virt_X;
			lastVY = cell.Virt_Y;

			startRec = rec;
			counter++;
			break;
		}
	}
	
	
	for(rec = startRec + 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			continue;

		if(cell.objt_cell.obj[OBJT_N_FA] != 0){
			retPh = Mov_xy_local(lastVX, lastVY, cell.Virt_X, cell.Virt_Y, 0, 0, 0, 0, angle, -1);
			if(retPh != PH_NORMAL)
				return(retPh);

			retPh  = Exec_Seq_DCI(cell.Virt_X, cell.Virt_Y);
			if(retPh != PH_NORMAL)
				return(retPh);

			lastVX = cell.Virt_X;
			lastVY = cell.Virt_Y;
			counter++;
		}
	}

	/*
	retPh = ChangeMast(FALC_MAST, MAIN_MAST);
	if(retPh != PH_NORMAL)
		return(retPh);
	*/

	fileIdx.num = F_MICE;
	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		if(mice.index != 0)
			mice.stopFlag = true;
		else
			break;
		retCnd = FileWrite(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);

	}
	*numCellChecked = counter;
	return(PH_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		DMPPlanner
**
** Description:		Execute planning for inspection of FA mounting places Tech. Cycle (1H)
**
** Output:			numCellChecked	- Number of cells checked by FA mounting places monitor (DMP)
**
** Return:			PHASTAT			- PH_NORMAL for success
**									- PH_XXXXXX otherwise
** 
**********************************************************************************************
*********************************************************************************************/
PHASTAT DMPPlanner(int *numCellChecked){
	RETCOND			retCnd;
	RETSTAT			retSt;
	PHASTAT			retPh;
	t_cell			cell;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	FILEIDX			fileIdx;
	GENIDX			reactZoneIdx;
	int				rec;
	GENIDX			mastType;
	short int		lastVX, lastVY;
	float			dynX, dynY;
	int				startRec;
	float			angle;
	int				counter;
	bool			tvMount;
	bool			insReact;
	micro_cmd_exe	mice;
	
	lastVX = 0;
	lastVY = 0;
	dynX = 0.0;
	dynY = 0.0;
	startRec = 0;
	counter = 0;
	*numCellChecked = 0;
	
	retCnd = GetTagIdx(TWN_TV_MOUNT, &tagIdx);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1)
		tvMount = true;
	else
		tvMount = false;

	retSt = GetZoneIdx(ZONE_REACTOR, &reactZoneIdx);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);
	
	fileIdx.num = F_CE01 + reactZoneIdx - 1;
	
	retSt = GetDynCurrentMast(&mastType);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);

	if(mastType != DMP_MAST)
		return(PH_FAILED);

	retSt = GetMastPosEx(mastType, &dynX, &dynY);
	if(retSt !=RT_NORMAL)
		return(PH_FAILED);

	//Controlla qui se DIMP � nel reattore e TV...//
	InsideReact(dynX, dynY, &insReact);
	if(!insReact){
		_stprintf_s(TCP_LogMsg, _T("Error: DIMP is not inside reactor."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	}

	if(tvMount){
		retSt = GetDynTVAngle(&angle);
		if(retSt != RT_NORMAL)
			return(PH_FAILED);	

		if((angle <= 135.0 - TOLL_MM) || (angle >= 135.0 + TOLL_MM)){
			_stprintf_s(TCP_LogMsg, _T("Error: TV mast must be at 135� to start DIMP technological cycle."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
	}
	
	for(rec = 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			continue;

		if(cell.type != CELL_FA)
			continue;

		if(cell.objt_cell.obj[OBJT_N_FA] != 0){
			MessageBox(NULL,_T("Technological Cycle 1H can't be executed because all reactor cells are not empty."), _T("Error"), MB_OK | MB_ICONERROR);
			return(PH_FAILED);
		}

		if((cell.objt_cell.obj[OBJT_N_FA] == 0)  && (cell.type == CELL_FA)){
			retPh = Mov_xy_local(0, 0, cell.Virt_X, cell.Virt_Y, dynX, dynY, 0, 0, angle, angle);
			if(retPh != PH_NORMAL)
				return(retPh);
			
			retPh = Exec_Seq_DMP(cell.Virt_X, cell.Virt_Y);
			if(retPh != PH_NORMAL)
				return(retPh);

			lastVX = cell.Virt_X;
			lastVY = cell.Virt_Y;

			startRec = rec;
			counter++;
			break;
		}
	}
	
	
	for(rec = startRec + 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &cell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		
		if((cell.Virt_X == 0) && (cell.Virt_Y == 0))
			continue;

		if(cell.objt_cell.obj[OBJT_N_FA] != 0){
			MessageBox(NULL,_T("Technological Cycle 1H can't be executed because all reactor cells are not empty."), _T("Error"), MB_OK | MB_ICONERROR);
			return(PH_FAILED);
		}

		if((cell.objt_cell.obj[OBJT_N_FA] == 0) && (cell.type == CELL_FA)){
			retSt = GetMastPosEx(FALC_MAST, &dynX, &dynY);
			if(retSt !=RT_NORMAL)
				return(PH_FAILED);
			
			if(cell.Virt_X == 307 && cell.Virt_Y == 342)
			{
				retPh = Mov_xy_local(lastVX, lastVY, 309, 341, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh = Mov_xy_local(309, 341, 307, 341, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh = Mov_xy_local(307, 341, 307, 342, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh  = Exec_Seq_DMP(307, 342);
				if(retPh != PH_NORMAL)
					return(retPh);

			}
			else if(cell.Virt_X == 307 && cell.Virt_Y == 316)
			{
				if(lastVX == 309 && lastVY == 316)
				{
					retPh = Mov_xy_local(lastVX, lastVY, 309, 317, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);

					retPh = Mov_xy_local(309, 317, 307, 317, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);
				}
				else
				{
					retPh = Mov_xy_local(lastVX, lastVY, 307, 317, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);
				}

				retPh = Mov_xy_local(307, 317, 307, 316, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh  = Exec_Seq_DMP(307, 316);
				if(retPh != PH_NORMAL)
					return(retPh);

			}
			else if(cell.Virt_X == 310 && cell.Virt_Y == 341)
			{
				if(lastVX == 307 && lastVY == 342)
				{
					retPh = Mov_xy_local(lastVX, lastVY, 307, 341, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);

					retPh = Mov_xy_local(307, 341, 310, 341, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);
				}	
				else
				{
					retPh = Mov_xy_local(lastVX, lastVY, 309, 341, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);

					retPh = Mov_xy_local(309, 341, 310, 341, 0, 0, 0, 0, angle, -1);
					if(retPh != PH_NORMAL)
						return(retPh);
				}

				retPh  = Exec_Seq_DMP(310, 341);
				if(retPh != PH_NORMAL)
					return(retPh);

			}
			else if(cell.Virt_X == 309 && cell.Virt_Y == 316)
			{
				retPh = Mov_xy_local(lastVX, lastVY, 309, 317, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh = Mov_xy_local(309, 317, 309, 316, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh  = Exec_Seq_DMP(309, 316);
				if(retPh != PH_NORMAL)
					return(retPh);

			}
			else
			{
				retPh = Mov_xy_local(lastVX, lastVY, cell.Virt_X, cell.Virt_Y, 0, 0, 0, 0, angle, -1);
				if(retPh != PH_NORMAL)
					return(retPh);

				retPh  = Exec_Seq_DMP(cell.Virt_X, cell.Virt_Y);
				if(retPh != PH_NORMAL)
					return(retPh);
			}


			lastVX = cell.Virt_X;
			lastVY = cell.Virt_Y;
			counter++;
		}
	}

	/*
	retPh = ChangeMast(FALC_MAST, MAIN_MAST);
	if(retPh != PH_NORMAL)
		return(retPh);
	*/

	fileIdx.num = F_MICE;
	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		if(mice.index != 0)
			mice.stopFlag = true;
		else
			break;
		retCnd = FileWrite(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);

	}
	*numCellChecked = counter;
	return(PH_NORMAL);
}

/*********************************************************************************************
**********************************************************************************************
**
** Function:		DMPPlannerSingle
**
** Description:		Execute planning for inspection of FA mounting place Tech. Cycle (1H1)
**
** Output:			---				- ---
**
** Return:			PHASTAT			- PH_NORMAL for success
**									- PH_XXXXXX otherwise
** 
**********************************************************************************************
*********************************************************************************************/
PHASTAT DMPPlannerSingle(void){
	RETCOND			retCnd;
	RETSTAT			retSt;
	PHASTAT			retPh;
	FILEIDX			fileIdx;
	t_cell			cell;
	TAGIDX			tagIdx;
	TAGVALEX		tagVal;
	GENIDX			reactZoneIdx;
	int				rec;
	GENIDX			mastType;
	float			dynX, dynY;
	float			angle;
	short int		phVx;
	short int		phVy;
	int				phase;
	bool			tvMount;
	bool			insReact;
	micro_cmd_exe	mice;
	
	dynX = 0.0;
	dynY = 0.0;
	
	retSt = GetDynNextPhase(&phase);
	retSt = GetPhaseDestVirtCoo(phase, &phVx, &phVy);

	retCnd = GetTagIdx(TWN_TV_MOUNT, &tagIdx);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	retCnd = TagRead(&tagIdx, &tagVal);
	if(retCnd != R_NORMAL)
		return(PH_FAILED);

	if(GtBit((unsigned short)(tagVal.value.val_di), 15) == 1)
		tvMount = true;
	else
		tvMount = false;

	retSt = GetZoneIdx(ZONE_REACTOR, &reactZoneIdx);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);
	
	retSt = GetDynCurrentMast(&mastType);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);

	if(mastType != DMP_MAST)
		return(PH_FAILED);

	retSt = GetMastPosEx(mastType, &dynX, &dynY);
	if(retSt !=RT_NORMAL)
		return(PH_FAILED);

	//Controlla qui se DIMP � nel reattore e TV...//
	InsideReact(dynX, dynY, &insReact);
	if(!insReact){
		_stprintf_s(TCP_LogMsg, _T("Error: DIMP is not inside reactor."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	}

	if(tvMount){
		retSt = GetDynTVAngle(&angle);
		if(retSt != RT_NORMAL)
			return(PH_FAILED);	

		if((angle <= 135.0 - TOLL_MM) || (angle >= 135.0 + TOLL_MM)){
			_stprintf_s(TCP_LogMsg, _T("Error: TV mast must be at 135� to start FALVL technological cycle."));
			TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
			SetDynStruc(tempDyn);
			return (PH_FAILED);
		}
	}
	
	retSt = GetCellVirtCoo(phVx, phVy, &cell);
	if(retSt != RT_NORMAL){
		_stprintf_s(TCP_LogMsg, _T("Error: cannot find destination cell information."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	}

	fileIdx.num = F_CE01 + reactZoneIdx - 1;

	t_cell tempCell;

	for(rec = 1; rec <= N_MAX_CELL; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &tempCell, sizeof(t_cell));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		
		if((tempCell.Virt_X == 0) && (tempCell.Virt_Y == 0))
			continue;

		if(tempCell.type != CELL_FA)
			continue;

		if(tempCell.objt_cell.obj[OBJT_N_FA] != 0){
			MessageBox(NULL, _T("Technological Cycle 1H1 can't be executed because all reactor cells are not empty."), _T("Error"), MB_OK | MB_ICONERROR);
			return(PH_FAILED);
		}
	}
		
	if((cell.objt_cell.obj[OBJT_N_FA] == 0)  && (cell.type == CELL_FA)){
		retPh = Mov_xy_local(0, 0, cell.Virt_X, cell.Virt_Y, dynX, dynY, 0, 0, angle, angle);
		if(retPh != PH_NORMAL)
			return(retPh);
			
		retPh = Exec_Seq_DMP(cell.Virt_X, cell.Virt_Y);
		if(retPh != PH_NORMAL)
			return(retPh);

	}
	else{
		_stprintf_s(TCP_LogMsg, _T("Error: cell is not free or wrong cell type."));
		TCP_LogFileWrite(_T("ERR"), TCP_LogMsg, TCP_ERR_CODE(46));
		SetDynStruc(tempDyn);
		return (PH_FAILED);
	
	}

	fileIdx.num = F_MICE;
	for(rec = 1; rec <= N_MAX_MICENR; rec++){
		retCnd = FileRead(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);
		if(mice.index != 0)
			mice.stopFlag = true;
		else
			break;
		retCnd = FileWrite(&fileIdx, rec, 1, &mice, sizeof(micro_cmd_exe));
		if(retCnd != R_NORMAL)
			return(PH_FAILED);

	}
	
	return(PH_NORMAL);
}

PHASTAT InsideReact(float x, float y, bool *inside){
	RETSTAT		retSt;
	float		radius;
	float		center_x;
	float		center_y;
	float		temp;

	retSt = GetInfiBlockValEx(8347, 0, TUNE_FROM_DAFS, &center_x);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);

	retSt = GetInfiBlockValEx(8348, 0, TUNE_FROM_DAFS, &center_y);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);

	retSt = GetInfiBlockValEx(8349, 0, TUNE_FROM_DAFS, &radius);
	if(retSt != RT_NORMAL)
		return(PH_FAILED);
	
	temp = ((x - center_x) * (x - center_x)) + ((y - center_y) * (y - center_y));

	if(temp <= (radius * radius))
		*inside = true;
	else
		*inside = false;

	return(PH_NORMAL);
}